use chrono::Local;
use image::{ExtendedColorType::Rgb8, Rgb, save_buffer};
use qrcode::QrCode;
use slint::{Image, Rgb8Pixel, SharedPixelBuffer};
use std::{cell::RefCell, env, rc::Rc};

slint::include_modules!();

pub fn run() -> Result<(), slint::PlatformError> {
    let window = MainWindow::new()?;

    let app = App {
        filename: Rc::new(RefCell::new(String::default())),
        save_count: Rc::new(RefCell::new(0)),
    };

    app.generate(&window);
    app.save(&window);

    window.run()
}

pub struct App {
    filename: Rc<RefCell<String>>,
    save_count: Rc<RefCell<u8>>,
}

impl App {
    /// 初始化
    pub fn new(filename: Rc<RefCell<String>>, save_count: Rc<RefCell<u8>>) -> Self {
        Self {
            filename,
            save_count,
        }
    }

    /// 生成二维码
    pub fn generate(&self, window: &MainWindow) {
        let weak = window.as_weak();
        let save_count = Rc::clone(&self.save_count);
        let filename = Rc::clone(&self.filename);

        window.on_generate(move || {
            let ui = weak.unwrap();
            let text = ui.get_content();
            let text = text.trim();
            let len = text.chars().count();
            let mut image = Image::default();

            if len == 0 {
                ui.invoke_show_prompt("内容不能为空".into(), false);
                ui.set_content("".into());
            } else if len > 300 {
                ui.invoke_show_prompt("仅支持300以内的字符".into(), false);
            } else {
                let img = QrCode::new(text)
                    .unwrap()
                    .render::<Rgb<u8>>()
                    .min_dimensions(232, 232)
                    .build();
                let buffer = SharedPixelBuffer::<Rgb8Pixel>::clone_from_slice(
                    img.as_raw(),
                    img.width(),
                    img.height(),
                );
                image = Image::from_rgb8(buffer);
                *save_count.borrow_mut() = 0;
                *filename.borrow_mut() =
                    format!("qrcode_{}", Local::now().format("%Y-%m-%d_%H%M%S"));
                ui.set_content("".into());
            }

            ui.set_qrcode(image);
        });
    }

    /// 保存二维码
    pub fn save(&self, window: &MainWindow) {
        let weak = window.as_weak();
        let save_count = Rc::clone(&self.save_count);
        let filename = Rc::clone(&self.filename);

        window.on_save(move || {
            let ui = weak.unwrap();
            let mut filename = filename.borrow().to_string();

            if *save_count.borrow() > 0 {
                filename += &format!("({})", save_count.borrow());
            }

            let res = rfd::FileDialog::new()
                .add_filter("PNG", &["png"])
                .set_file_name(filename + ".png")
                .set_directory(env::current_dir().unwrap())
                .save_file();
            if let Some(path) = res {
                let img = ui.get_qrcode().to_rgb8().unwrap();
                save_buffer(path, img.as_bytes(), img.width(), img.height(), Rgb8).unwrap();
                *save_count.borrow_mut() += 1;
                ui.invoke_show_prompt("保存成功".into(), true);
            }
        });
    }
}
